package com.company.project.common.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author json
 * /有销接口
 * @date 2021/11/11  10:00
 * @description 有销demo
 * 使用前,需要先导入maven依赖,方可使用:
 * <dependency>
 * <groupId>cn.hutool</groupId>
 * <artifactId>hutool-all</artifactId>
 * <version>5.7.4</version>
 * </dependency>
 * appId：8csa72721c4613a8583cb91bcadf
 * appSecret：6A47E33DBD0D87ABDEC5FC35C6916B91
 *1808040113486192642
 * ibkVWTbIzFYB1YRi
 * 0215180135
 **/

public class YdDjCall {
    /**
     * 连连线路
     */

    /**
     * key：5083150942470149
     * secrect：2619b5691cfc91d529c58daffa96a2e7
     */
    //请求主机地址
    private static String HOST = "https://api.51lianlian.cn";

    /**
     * 绑定路径
     */
    private static String CALLURL = "/api/v1/binding";

    //接口的key
    private static String ACCESSKEY = "5083150942470149";
    //接口的盐
    private static String ACCESSSECRET = "2619b5691cfc91d529c58daffa96a2e7";

    /**
     * 回调地址  https://yundianhu.cc/index/callbak/llline
     */

    /**
     *
     * Header 中需要携带的公共参数如下
     * 字段名称 字段类型 约束限制 说明
     * Content-Type string(32) 必选 application/json;charset=UTF-8
     * api_key string(32) 必选 企业 id，用于调用者声明身份
     * sign string(64) 必选 参数签名，用于安全校验参数完整性和调用
     * 者的合法性，防止中间人篡改参数和未授权
     * 调用
     *
     * 字段名称 字段类型 约束 说明
     * ts int 必选 时间戳
     * type string(16) 必选 绑定类型
     * TYC 双呼
     * callerId string(32) 必选 主叫坐席编号
     * callerNos Array string 必选 主叫号码 （部分线路需认证）
     * ["130xxxx1122"]
     * calledId string(50) 客户编号，话单推送时回传
     * calledName string(50) 客户姓名，话单推送时回传
     * calledNo string(20) 必选 需要呼叫的客户号码 固话需带区号
     * transferNo string(32) 指定中间号，空时由系统分配
     * payload string(1024) 扩展信息，话单推送时回传
     */



    /****************************************    线路2 参数end ************************************************************/
    /**
     * 调用实例
     */
    public static void main(String[] args) {
        //拨打方法调用
        //HttpResponse bind = bind("13995523002", "17007142610", "+869717572192", null);
        HttpResponse bind = bind2("15100107200", "18131958550", "0215180135", null,null,null,null);
        JSONObject body = JSONUtil.parseObj(bind.body());
        if (!body.containsKey("code") || !"200".equals(body.get("code"))) {
            throw new RuntimeException(body.getStr("msg"));
        }
        String bindId = JSONUtil.parseObj(body.get("data")).getStr("sessionId");
        System.out.println(bindId);


    }
    public static void callOut() {
        Map<String, Object> p = new HashMap<>();
        p.put("ts", System.currentTimeMillis() / 1000);
        p.put("type", "TYC");//固定传 TYC
        p.put("callerId", "员工编号（坐席编号）");//联系管理员开通账户，同时提供员工编号
        List<String> callerNoList = new ArrayList<>();
        callerNoList.add("183xxxx3005");
        p.put("callerNos", callerNoList);
        p.put("calledNo", "被叫号码");
        p.put("payload", "扩展字段");//话单推送时回传
        String sign = stringToMD5((new Gson().toJson(p) + "替换成自己的secret"));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("api_key", "替换成自己的 key");
        headers.add("sign", sign);
        HttpEntity<String> entity = new HttpEntity<>(new Gson().toJson(p), headers);
        ResponseEntity<String> resp = new RestTemplate(new
                SimpleClientHttpRequestFactory()).postForEntity("https://api" +
                ".51lianlian.cn/api/v1/binding", entity, String.class);
        System.out.println("resp-------->" + resp.getBody());
    }
    public static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        String md5code = new BigInteger(1, secretBytes).toString(16);
        int length = 32 - md5code.length();
        for (int i = 0; i < length; i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }
    /**
     * @param callerNbr       主叫
     * @param calleeNbr       被叫
     * @param bindNbr       中间号
     * @param notifyUrl  回调地址 (可以为空)
     * @return 返回绑定后返回请求相应
     * <p>
     * {
     * "code": 200,
     * "msg": "请求成功",
     * "data": {
     * "sessionId": "1432233693284847617",
     * "bindNbr": "16036760901"
     * }
     * }
     */
    public static HttpResponse bind(String callerNbr, String calleeNbr, String bindNbr, String notifyUrl) {

        Map<String, Object> p = new HashMap<>();
        p.put("ts", System.currentTimeMillis() / 1000);
        p.put("type", "TYC");//固定传 TYC
        p.put("callerId", "1001");//员工编号（坐席编号）   联系管理员开通账户，同时提供员工编号
        List<String> callerNoList = new ArrayList<>();//主叫号码
        callerNoList.add(callerNbr);
        p.put("callerNos", callerNoList);
        p.put("calledNo", calleeNbr);//被叫号码
//        p.put("transferNo", bindNbr);//中间号
//        p.put("payload", "扩展字段");//话单推送时回传
        String sign = stringToMD5((new Gson().toJson(p) + ACCESSSECRET));
        Map<String, String> head = new HashMap<>();
        head.put("Content-Type", "application/json");
        head.put("api_key", ACCESSKEY);
        head.put("sign", sign);

        JSONObject json = new JSONObject(p);
        System.out.println("json:"+json);
        System.out.println("sign:"+head.get("sign"));
        System.out.println("IP地址:"+HOST + CALLURL);
        System.out.println("回调IP地址:"+HOST + CALLURL);
        return HttpUtil.createPost(HOST + CALLURL)
                .headerMap(head, true)
                .body(new Gson().toJson(p))
                .timeout(10000)
                .execute();
    }

    /**
     * @param callerNbr       主叫
     * @param calleeNbr       被叫
     * @param bindNbr       中间号
     * @param notifyUrl  回调地址 (可以为空)
     * @param appid  appid
     * @param appsecret  密钥
     * @param host  请求主机地址
     * @param callurl  绑定路径
     * @return 返回绑定后返回请求相应
     * <p>
     * {
     * "code": 200,
     * "msg": "请求成功",
     * "data": {
     * "sessionId": "1432233693284847617",
     * "bindNbr": "16036760901"
     * }
     * }
     */
    public static HttpResponse bindLine(String callerNbr, String calleeNbr, String bindNbr, String notifyUrl,String appid, String appsecret ,String host, String callurl) {
        Map<String, Object> body = new HashMap<>();
        //请求体map
        body.put("appId", appid);
        body.put("callerNbr", callerNbr);
        body.put("calleeNbr", calleeNbr);
        body.put("bindNbr", bindNbr);
        //回调地址参数(可以传,也可以不传,不传则不回调)
        if (notifyUrl != null && !"".equals(notifyUrl) && notifyUrl.trim().length() > 0) {
            body.put("notifyUrl", notifyUrl);
        }
        String sign = sign(body, appsecret);
        body.put("sign", sign);
        return HttpUtil.createPost(host + callurl)
                .headerMap(head(), true)
                .body(JSONUtil.parseFromMap(body).toString())
                .execute();
    }

    /**
     * 创建请求头
     */
    private static Map<String, String> head() {
        //请求头map
        Map<String, String> head = new HashMap<>();
        head.put("Content-Type", "application/json;charset=utf-8");
        return head;
    }

    /**
     * 签名
     *
     * @param map          请求参数
     * @param accessSecret 盐
     * @return 返回加密后, 转大写的字符串
     */
    public static String sign(Map<String, Object> map, String accessSecret) {
        StringBuilder sb = new StringBuilder(accessSecret);
        for (Map.Entry entry : MapUtil.sort(map).entrySet()) {
            if (ObjectUtil.isNotEmpty(entry.getValue())) {
                sb.append(entry.getKey()).append(entry.getValue());
            }
        }
        System.out.println("sb:"+sb.toString());
        return SecureUtil.md5(sb.toString()).toUpperCase();
    }

    /**
     * @param telA       主叫
     * @param telB       被叫
     * @param telX       中间号，非共享号码池线路必须传此参数
     * @param notifyUrl  回调地址 (可以为空)
     * @param channel  共享号码池线路通道，使用此参数表示使用共享号码池 线路，系统将自动分配中间号，无需传 telX。  取值范围： 16-电信回拨
     * @param expire  绑定时间（自动解绑时间，秒）
     * @param notifyData  话单回调自定义数据，在回调时将回传此值
     * @return 返回绑定后返回请求相应
     * <p>
     * {
     * "code": 200,
     * "msg": "请求成功",
     * "data": {
     * "sessionId": "1432233693284847617",
     * "bindNbr": "16036760901"
     * }
     * }
     */
    public static HttpResponse bind2(String telA, String telB, String telX, String notifyUrl,Integer channel,Integer expire,String notifyData) {
        Map<String, Object> body = new HashMap<>();
//        //请求体map
        body.put("accessKey", ACCESSKEY);
        body.put("telA", telA);
        body.put("telB", telB);
        body.put("telX", telX);
        if (channel != null && channel >=0) {
            body.put("channel", channel);
        }
        if (expire != null && expire >=0) {
            body.put("expire", expire);
        }
        if (Func.isNotEmpty(notifyData)) {
            body.put("notifyData", notifyData);
        }
        //回调地址参数(可以传,也可以不传,不传则不回调)
        if (notifyUrl != null && !"".equals(notifyUrl) && notifyUrl.trim().length() > 0) {
            body.put("notifyUrl", notifyUrl);
        }
        String sign = sign(body, ACCESSSECRET);
        body.put("sign", sign);

        JSONObject json = new JSONObject(body);
        System.out.println("json:"+json);
        System.out.println("sign:"+body.get("sign"));
        System.out.println("IP地址:"+HOST + CALLURL);
        return HttpUtil.createPost(HOST + CALLURL)
                .headerMap(head(), true)
                .body(JSONUtil.parseFromMap(body).toString())
                .execute();
//        return  null;
    }
}
